package lib.checkrep;

import lib.util.StringUtil;


public abstract class ArrayStringCheck {
  //bound array length
  public static boolean LengthInRange(String[] arr, int lower_bound, int upper_bound) {
    return arr.length >= lower_bound && arr.length <= upper_bound;
  }

  //bound the length of each strings in an array of strings [lower_bound, upper_bound]
  public static boolean ElementsLengthInRange(String[] arr, int lower_bound, int upper_bound) {
    for (String str : arr) {
      if (str.length() < lower_bound || str.length() > upper_bound) return false;
    }
    return true;
  }

  //asserts that the length of all the elements of the array string is equal
  public static boolean ElementsLengthEqual(String[] arr) {
    for (String str : arr) {
      if (str.length() != arr[0].length()) return false;
    }
    return true;
  }

  //check if characters in the array of string contains only specified characters.
  public static boolean ContainsOnly(String arr[], String characters) {
    for (String str : arr) {
      if (!StringCheck.ContainsOnly(str, characters)) return false;
    }
    return true;
  }

  // check if array of string contains X occurences of any element of chars,
  // where X is inclusively between lower_bound and upper_bound
  public static boolean ContainsXOccurencesOf(String[] arr, String chars, int lower_bound, int upper_bound) {
    int occ = 0;
    for (String str : arr) {
      for (int i = 0; i < str.length(); ++i) {
        if (chars.contains(String.valueOf(str.charAt(i)))) {
          ++occ;
        }
      }
    }
    return occ >= lower_bound && occ <= upper_bound;
  }

  /**
   * check if SQUARE array of string is symmetric with respect to the main diagonal
   */
  public static boolean Symmetric(String[] arr) {
    if (!ArrayStringCheck.ElementsLengthInRange(arr, arr.length, arr.length)) {
      return false;
    }
    for (int i = 0; i < arr.length; ++i) {
      for (int j = 0; j < arr.length; ++j) {
        if (arr[i].charAt(j) != arr[j].charAt(i)) {
          return false;
        }
      }
    }
    return true;
  }

  /**
   * Checks if the main diagonal of the SQUARE input matrix contains characters
   * in allowed
   */
  public static boolean DiagonalContainsOnly(String[] arr, String allowed) {
    if (!ArrayStringCheck.ElementsLengthInRange(arr, arr.length, arr.length)) {
      return false;
    }
    for (int i = 0; i < arr.length; ++i) {
      if (!allowed.contains(String.valueOf(arr[i].charAt(i)))) return false;
    }
    return true;
  }

  /**
   * Checks if the array has no two identical elements.
   */
  public static boolean ElementsDistinct(String[] arr) {
    for (int i = 0; i < arr.length; ++i) {
      for (int j = i+1; j < arr.length; ++j) {
        if (arr[i].equals(arr[j])) {
          return false;
        }
      }
    }
    return true;
  }
  
  /**
   * Checks if all four borders of the array has X occurences of any of the
   * specified characters.
   */
  public static boolean BorderContainsXOccurrencesOf(
      String[] arr, String alphabet, int lower_bound, int upper_bound) {
    if (!StringCheck.StringContainsXOccurrencesOf(
        arr[0], alphabet, lower_bound, upper_bound)) return false;
    if (!StringCheck.StringContainsXOccurrencesOf(
        arr[arr.length - 1], alphabet, lower_bound, upper_bound)) return false;
    
    String[] transposed_arr =
        StringUtil.charArrayToStringArray(
            StringUtil.Transpose(
                StringUtil.StringArrayToCharArray(arr)));
    
    if (!StringCheck.StringContainsXOccurrencesOf(
        transposed_arr[0], alphabet, lower_bound, upper_bound)) return false;
    if (!StringCheck.StringContainsXOccurrencesOf(
        transposed_arr[transposed_arr.length - 1], alphabet, lower_bound, upper_bound)) {
      return false;
    }
    
    return true;
  }
};